package com.hzlh.controller;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.hzlh.common.util.ChinesePinyinUtils;
import com.hzlh.common.util.GsonSerializerUtils;
import com.hzlh.domain.po.PermissionsPo;
import com.hzlh.domain.po.RolePermPo;
import com.hzlh.domain.po.RolePo;
import com.hzlh.log.MethodLog;
import com.hzlh.service.RolePermService;
import com.hzlh.shiro.ShiroUser;

@Controller
@RequestMapping("permission")
public class PermissionsController {
	
	//获取下拉节点数据
	public List<PermissionsPo> list = new ArrayList<PermissionsPo>();
	
	@Autowired
	private RolePermService rolePermService;

	/**
	 * @Description: 获取权限分页列表数据
	 * @param pageIndex 当前页数
	 * @param level 等级
	 * @param name 名称
	 * @param pageSize 记录条数
	 * @return Map<String,Object>  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月10日 下午3:34:26
	 */
	@MethodLog(key="PERMISSION.LIST")
	@RequiresPermissions("permission:list")
	@RequestMapping("/page")
	@ResponseBody
	public Map<String,Object> page(
			@RequestParam(value="permLevel",required=false)String permLevel,
			@RequestParam(value="permName",required=false)String permName, 
			@RequestParam(value="parentId",required=false)Long parentId, 
			int pageIndex,int pageSize){
		return rolePermService.permPage(permLevel, permName, parentId, pageIndex, pageSize);
	}
	
	/**
	 * @Description: 获取权限树状列表
	 * @return List<PermissionsPo>  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月15日 下午4:23:43
	 */
	@RequestMapping("/treeList")
	@ResponseBody
	public List<PermissionsPo> treeList(@RequestParam(value="roleId",required=false) Long roleId){
		return refactorTree(roleId,rolePermService.permTreeList());
	}
	
	@RequestMapping("/tree")
	@ResponseBody
	public List<PermissionsPo> tree(@RequestParam(value="filterId",required=false) Long filterId){
		Subject subject = SecurityUtils.getSubject();
		ShiroUser shiroUser = (ShiroUser)subject.getPrincipal();
		List<RolePo> rolesList= shiroUser.getUser().getRoles();
		int weight=rolesList.get(0).getWeight();
		Map<String, Object> map = new HashMap<String ,Object>();
		if(filterId != null){
			map.put("filter_id", filterId);
		}
		map.put("weight",weight);
		map.put("enables", PermissionsPo.ENABLE_YES);
		return rolePermService.getAllPermissions(map);
	}
	
	@RequestMapping("/menuTree")
	@ResponseBody
	public List<PermissionsPo> menuTree(){
		list.clear();
		List<PermissionsPo> parents = rolePermService.permTreeList();
		for (PermissionsPo parentPo : parents) {
			list.add(parentPo);
			List<PermissionsPo> childrens = parentPo.getPermissions();
			for (PermissionsPo childrenPo : childrens) {
				list.add(childrenPo);
			}
		}
		return list;
	}
	
	@RequestMapping("/zTree")
	@ResponseBody
	public List<PermissionsPo> zTree(){
		Subject subject = SecurityUtils.getSubject();
		ShiroUser shiroUser = (ShiroUser)subject.getPrincipal();
		List<RolePo> rolesList= shiroUser.getUser().getRoles();
		int weight=rolesList.get(0).getWeight();
		List<PermissionsPo> treeList = new ArrayList<>();
		PermissionsPo po = new PermissionsPo();
		po.setId(PermissionsPo.DEFAULT_ID);
		po.setPermName(PermissionsPo.DEFAULT_ALL_TEXT);
		po.setParentId(PermissionsPo.DEFAULT_PID);
		treeList.add(po);
		Map<String, Object> map = new HashMap<String ,Object>();
		map.put("weight",weight);
		map.put("filter_level", PermissionsPo.THREE_LEVEL);//过滤第三级别
		List<PermissionsPo> result = rolePermService.getAllPermissions(map);
		if(result.size() > 0){
			treeList.addAll(result);
		}
		return treeList;
	}
	
	/**
	 * @Description: 重构树状结构（级别重构）- 二级节点
	 * @param result
	 * @return List<PermissionsPo>  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月15日 下午4:35:13
	 */
	public List<PermissionsPo> refactorTree(Long roleId,List<PermissionsPo> result){
		List<PermissionsPo> rs = new ArrayList<PermissionsPo>();
		List<Long> selectedIds = rolePermService.getRolePermIds(roleId);//已选择权限Id集合
		//结果集遍历
		for (PermissionsPo parentPo : result) {
			//先取出二级节点数据
			for (PermissionsPo childrenPo : parentPo.getPermissions()) {
				if(childrenPo.getPermLevel() == PermissionsPo.TWO_LEVEL){
					//三级节点-是否已选中
					for (PermissionsPo permission : childrenPo.getPermissions()) {
						isChecked(selectedIds, permission);
					}
					isChecked(selectedIds, childrenPo);
					rs.add(childrenPo);//将其二级节点添加，及下面子节点数据保留
				}
			}
			//父节点数据取出重构树状，清除子节点数据
			if(parentPo.getPermLevel() == PermissionsPo.ONE_LEVEL){
				parentPo.getPermissions().clear();//清除
				isChecked(selectedIds, parentPo);
				rs.add(parentPo);
			}
		}
		return rs;
	}
	
	public void isChecked(List<Long> selectedIds,PermissionsPo permissionsPo){
		//ID不会存在重复数值
		if(selectedIds.size() > 0 && selectedIds.contains(permissionsPo.getId())){
			permissionsPo.setChecked(true);//存在true勾选
		}
	}
	
	/**
	 * @Description: 新增权限初始化跳转
	 * @return String  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月10日 下午3:32:44
	 */
	@RequiresPermissions("permission:add")
	@RequestMapping("/add")
	public String add() {
		return "permission/add";  
	}
	
	/**
	 * @Description: 编辑权限
	 * @param model
	 * @param id
	 * @return String  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月10日 下午3:31:23
	 */
	@RequiresPermissions("permission:edit")
	@RequestMapping("/edit")
	public String edit(Model model, Long id){
		PermissionsPo po = rolePermService.getPerm(id);
		model.addAttribute("po", po);
		return "permission/edit";
	}
	 
	/**
	 * @Description: 权限保存或修改
	 * @param po
	 * @return String  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月10日 下午3:30:53
	 */
	@MethodLog(key="PERMISSION.SAVE")
	@RequiresPermissions(value={"permission:save","permission:update"},logical=Logical.OR)
	@RequestMapping("/save")
	@ResponseBody
	public boolean save(PermissionsPo po){
		boolean result = false;
		//判断是否为空，如果不为空视为更新，否则，新增
		if(po.getId() != null){
			result = rolePermService.editPerm(po) > 0;
		}else{
			int maxNum = rolePermService.getRankNum(po.getParentId());
			String code = ChinesePinyinUtils.getPinYinHeadChar(po.getPermName());//自动识别中文字首字母作为code
			po.setPermCode(code);
			po.setRanking(maxNum);
			po.setEnables(PermissionsPo.ENABLE_YES);//默认启用
			//如果上级为空并且等级也为空的情况视为父节点
			if(po.getPermLevel() == null && po.getParentId() == null){
				po.setPermLevel(PermissionsPo.ONE_LEVEL);//默认一级
			}
			result = rolePermService.addPerm(po) > 0;
		}
		return result;
	}
	
	/**
	 * @Description: 删除权限（单个或批量）
	 * @param id
	 * @return boolean  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月3日 下午4:16:33
	 */
	@MethodLog(key="PERMISSION.DELETE")
	@RequiresPermissions("permission:delete")
	@RequestMapping("/delete")
	@ResponseBody
	public boolean delete(Long[] ids){
		rolePermService.deleteRolePermIds(ids);///清除关联
		return rolePermService.deletePerm(ids);
	}
	
	/**
	 * @Description: 保存角色权限配置
	 * @param data
	 * @return String  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月15日 下午6:19:09
	 */
	@MethodLog(key="ROLE.ALLOT")
	@RequiresPermissions("allot:save")
	@RequestMapping("/saveRolePermTree")
	@ResponseBody
	public boolean saveRolePerm(Long[] roleIds,Long[] permissionIds){
		List<RolePermPo> result = new ArrayList<RolePermPo>();
		if(roleIds != null &&  permissionIds.length > 0){
			for (Long roleId : roleIds) {
				for (Long permId : permissionIds) {
					RolePermPo po = new RolePermPo();
					po.setPermId(permId);
					po.setRoleId(roleId);
					result.add(po);
				}
			}
		    
			if(result.size() > 0){
				rolePermService.deleteRolePerm(roleIds);///清除旧数据
				rolePermService.batchAddRolePerm(result);//添加新配置
			}
		}else{
			rolePermService.deleteRolePerm(roleIds);///清除旧数据
		}
		return true;
	}
	
	/**
	 * @Description: TODO
	 * @param checked
	 * @param roleId
	 * @param permissionId
	 * @param rolePermPo
	 * @param result void  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月18日 上午10:31:50
	 */
	public void addResultList(boolean checked, Long roleId, Long permissionId,
			RolePermPo rolePermPo,
			List<RolePermPo> result){
		if(checked){
			rolePermPo = new RolePermPo();
			rolePermPo.setRoleId(roleId);
			rolePermPo.setPermId(permissionId);
			result.add(rolePermPo);
		}
	}
	
	/**
	 * @Description: 更改状态
	 * @param id
	 * @param status
	 * @return boolean  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月17日 下午3:56:23
	 */
	@MethodLog(key="PERMISSION.STATUS")
	@RequiresPermissions("permission:status")
	@RequestMapping(value="/updateStatus",method=RequestMethod.POST)
	@ResponseBody
	public boolean updateStatus(PermissionsPo po){
		return rolePermService.editPerm(po) > 0 ? true:false;
	}
	
	/**
	 * @Description: 保存排序
	 * @param data
	 * @return boolean  
	 * @throws
	 * @author liu_wenfeng
	 * @date 2014年9月16日 下午8:16:32
	 */
	@MethodLog(key="PERMISSION.SORT")
	@RequiresPermissions("permission:sort")
	@RequestMapping(value="/saveSort",method=RequestMethod.POST)
	@ResponseBody
	public boolean saveSort(String data){
		Gson gson = new GsonBuilder().registerTypeAdapter(
				Date.class, 
				new GsonSerializerUtils()).setDateFormat(DateFormat.LONG).create();
		List<PermissionsPo> list = gson.fromJson(data, new TypeToken<List<PermissionsPo>>(){}.getType());
		return rolePermService.updatePermSort(list) > 0 ? true:false;
	}
}
